package com.tyut.musicdreamer.service.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 用户ID传播过滤器
 * 确保用户ID在请求头中存在，以便下游服务使用
 * 此过滤器只负责从其他来源（Cookie、URI参数等）获取用户ID
 */
@Component
@Slf4j
public class UserIdPropagationFilter implements GlobalFilter, Ordered {

    /**
     * 用户ID请求头名称
     */
    public static final String USER_ID_HEADER = "X-User-Id";
    
    /**
     * Cookie中保存的用户ID名称
     */
    private static final String USER_ID_COOKIE = "userId";
    
    /**
     * Authorization请求头中的用户ID前缀
     */
    private static final String USER_ID_PREFIX = "userId:";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 记录原始请求
        log.debug("UserIdPropagationFilter处理请求: {}, 路径: {}", request.getMethod(), request.getPath());
        
        // 检查请求头是否已包含用户ID
        if (request.getHeaders().containsKey(USER_ID_HEADER)) {
            log.debug("请求头中已有用户ID: {}", request.getHeaders().getFirst(USER_ID_HEADER));
            return chain.filter(exchange);
        }
        
        // 从其他来源获取用户ID
        String userId = getUserIdFromRequest(request);
        
        // 如果获取到用户ID，添加到请求头
        if (StringUtils.hasText(userId)) {
            ServerHttpRequest newRequest = request.mutate()
                    .header(USER_ID_HEADER, userId)
                    .build();
            
            log.debug("从其他来源添加用户ID到请求头: {}", userId);
            
            // 继续过滤器链，使用更新后的请求
            return chain.filter(exchange.mutate().request(newRequest).build());
        }
        
        // 未找到用户ID，继续处理请求
        log.debug("未找到用户ID，继续处理请求");
        return chain.filter(exchange);
    }
    
    /**
     * 从请求中获取用户ID
     */
    private String getUserIdFromRequest(ServerHttpRequest request) {
        // 1. 尝试从Authorization头获取
        String authorization = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
        if (StringUtils.hasText(authorization) && authorization.startsWith(USER_ID_PREFIX)) {
            String userId = authorization.substring(USER_ID_PREFIX.length());
            log.debug("从Authorization请求头获取用户ID: {}", userId);
            return userId;
        }
        
        // 2. 尝试从Cookie获取
        HttpCookie cookie = request.getCookies().getFirst(USER_ID_COOKIE);
        if (cookie != null && StringUtils.hasText(cookie.getValue())) {
            log.debug("从Cookie获取用户ID: {}", cookie.getValue());
            return cookie.getValue();
        }
        
        // 3. 从URI参数获取
        String userIdParam = request.getQueryParams().getFirst("userId");
        if (StringUtils.hasText(userIdParam)) {
            log.debug("从URI参数获取用户ID: {}", userIdParam);
            return userIdParam;
        }
        
        return null;
    }

    @Override
    public int getOrder() {
        // 在SaTokenUserIdFilter之后执行
        return -90;
    }
} 